package com.hoe.tsb.fraft.enums;

import com.alibaba.fastjson.JSON;
import com.hoe.tsb.fraft.Node;
import com.hoe.tsb.fraft.event.msg.FRaftMessage;
import com.hoe.tsb.fraft.event.msg.Heartbeat;
import com.hoe.tsb.fraft.serialize.EnumsSerializer;
import com.hoe.tsb.fraft.serialize.Serializer;
import lombok.Getter;

import java.util.List;

/**
 * <p>
 * 消息类型
 * </p>
 *
 * @author hoe
 * @version 1.0
 * @date 2022/11/21
 */
public enum MessageType implements EnumsSerializer<MessageType> {
    /**
     * 回复
     */
    ACK(false),
    /**
     * 拉票
     */
    CANVASS,
    /**
     * 投票
     */
    VOTE,
    /**
     * 纠正（当节点落后任期时，任意节点收到落后节点消息，均告知当前Leader信息以纠正落后信息）
     */
    CORRECT,
    /**
     * 溯源数据
     */
    TRACE,
    /**
     * 区块数据
     */
    BLOCK,
    /**
     * 日志同步
     */
    SYNC,
    /**
     * 心跳
     */
    HEARTBEAT;

    @Getter
    private final boolean needAck;

    MessageType() {
        this(true);
    }

    MessageType(boolean needAck) {
        this.needAck = needAck;
    }

    public static Integer ser(MessageType enu) {
        return MessageType.values()[0].serialize(enu);
    }

    /**
     * 反序列化枚举本身
     * @param ordinal 枚举下标
     * @return 枚举
     */
    public static MessageType des(Integer ordinal) {
        return (MessageType) MessageType.values()[0].deserialize(ordinal);
    }

//    /**
//     * 反序列化枚举代表的FRaft对象
//     * @param src 待反序列化数据（全字节
//     * @return 反序列化的对象
//     */
//    public static <O extends FRaftMessage<O>> O desObject(byte[] src) {
//        byte firstByte = src[0];
//        MessageFlag messageFlag = MessageFlag.des(firstByte & 0x1F);
//        MessageType messageType = des(firstByte >> 5);
//        //设置为空字符
//        src[0] = 0;
//
//        O o = desObject(messageType, src);
//        o.setFlag(messageFlag);
//        o.setType(messageType);
//        return o;
//    }
//
//    /**
//     * 反序列化枚举代表的FRaft对象
//     * @param src 待反序列化数据
//     * @param <O> 反序列化的目标对象泛型
//     * @return 反序列化的对象
//     */
//    @SuppressWarnings("unchecked")
//    private static <O extends FRaftMessage<O>> O desObject(MessageType messageType, byte[] src) {
//        return (O) JSON.parseObject(new String(src), messageType.getTargetCls());
//    }
}
